/**
 * md5.h
 * md5 header
 *
 * @auther Miles Dung
 * @date May 26 2011
 *
 * This file is part of md5 net based cracker project, which
 * released under the GNU GPL v2 or v3 (whichever you like)
 * This project is distributed in the hope that it will be
 * useful, but WITHOUT ANY WARRANTY, without even the implied
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 * PURPOSE. See the GNU General Public License for more details.
 */
#ifndef MD5_H_INCLUDED
#define MD5_H_INCLUDED
#include <fstream>
#include <sstream>
#include <iostream>
#include <cstring>
#include <cstdlib>

using namespace std;
#define X86
#ifdef X86
typedef long long int UINT_64;
typedef unsigned int UINT_32;
typedef unsigned short UINT_16;
typedef unsigned char UINT_8;
#endif

class md5
{
public:
    md5(string& str);
    md5(ifstream& fin);
    void md5_init();
    void md5_calc();
    string md5_get_hash();
private:
    //four chaining varibles
    const static UINT_32 A=0x67452301;
    const static UINT_32 B=0xefcdab89;
    const static UINT_32 C=0x98badcfe;
    const static UINT_32 D=0x10325476;

    UINT_32 a, b, c, d;

    union md5_dig_t
    {
        UINT_8  dig8[64];
        UINT_16 dig16[32];
        UINT_32 dig32[16];
        UINT_64 dig64[8];
    } digest;

    union md5_res_t
    {
        UINT_8 res8[16];
        UINT_32 res32[4];
    } result;

    inline UINT_32 F(UINT_32 X,UINT_32 Y,UINT_32 Z);
    inline UINT_32 G(UINT_32 X,UINT_32 Y,UINT_32 Z);
    inline UINT_32 H(UINT_32 X,UINT_32 Y,UINT_32 Z);
    inline UINT_32 I(UINT_32 X,UINT_32 Y,UINT_32 Z);

    inline void FF(UINT_32& a, UINT_32 b, UINT_32 c, UINT_32 d,
                   UINT_32 Mj, UINT_32 s, UINT_32 ti);
    inline void GG(UINT_32& a, UINT_32 b, UINT_32 c, UINT_32 d,
                   UINT_32 Mj, UINT_32 s, UINT_32 ti);
    inline void HH(UINT_32& a, UINT_32 b, UINT_32 c, UINT_32 d,
                   UINT_32 Mj, UINT_32 s, UINT_32 ti);
    inline void II(UINT_32& a, UINT_32 b, UINT_32 c, UINT_32 d,
                   UINT_32 Mj, UINT_32 s, UINT_32 ti);
};

#endif // MD5_H_INCLUDED
